﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Diagnostics;

namespace IGolovkine.AoA.Tests
{
    [TestClass]
    public class ChannelTests
    {
        private TimeSpan GetTimeOut()
        {
            if (Debugger.IsAttached)
            {
                Debugger.Log(1, "Trace", "Timeout is set to 1 seconds");
                return TimeSpan.FromSeconds(1);
            }
            else
            {
                Debugger.Log(1, "Trace", "Timeout is set to 100 ms");
                return TimeSpan.FromMilliseconds(100);
            }
        }

        [TestMethod]
        public void TestChannelTest()
        {
            ChannelTestBed<int> channel = new ChannelTestBed<int>(this.GetTimeOut());

            Assert.AreSame(channel.Input, channel.InputSubject);
            Assert.AreSame(channel.Output, channel.OutputSubject);

            channel.InputSubject.OnNext(1);
            Assert.AreEqual(1, channel.PopLastInput().Current);

            AssertEx.Throws<TimeoutException>(()=> channel.PopLastInput());
            channel.Input.OnNext(2);
            Assert.AreEqual(2, channel.PopLastInput().Current);

            AssertEx.Throws<TimeoutException>(() => channel.PopLastInput());
        }
       
        [TestMethod]
        public void ChannelSpec()
        {
            ChannelTestBed<int> channel = new ChannelTestBed<int>(this.GetTimeOut());

            channel.InputSubject.OnNext(1);
            Assert.AreEqual(1, channel.PopLastInput().Current);

            channel.InputSubject.OnNext(2);
            Assert.AreEqual(2, channel.PopLastInput().Current);

            //channel.InputSubject.OnError(new Exception());
            //Assert.AreEqual(NotificationKind.OnError, channel.PopLastInput().Kind);

            channel.InputSubject.OnCompleted();

            //AssertEx.Throws<TimeoutException>(()=> channel.PopLastInput());
            Assert.AreEqual(NotificationKind.OnCompleted, channel.PopLastInput().Kind);

            ///
            /// Output
            ///

            channel.OutputSubject.OnNext(3);
            Assert.AreEqual(3, channel.PopLastOutput().Current);

            channel.OutputSubject.OnNext(4);
            Assert.AreEqual(4, channel.PopLastOutput().Current);

            channel.OutputSubject.OnError(new Exception());
            Assert.AreEqual(NotificationKind.OnError, channel.PopLastOutput().Kind);

            channel.OutputSubject.OnCompleted();
            AssertEx.Throws<TimeoutException>(() => channel.PopLastOutput());

        }
    }
}
